﻿#pragma once
#include <string>
#include <vector>
#include <functional>
#include <fstream>
using ProcessFuncCB = std::function<void(std::string&)>;

class filepath
{
public:
    filepath();
    filepath(const filepath& rhs);
    explicit filepath(const std::string& pathname);

    filepath& operator=(const filepath& rhs) {
        set(rhs);
        return *this;
    }

    void set(const filepath& rhs);
    const std::string& string() const { return _PathName; }
    const char* c_str() const { return _PathName.c_str(); }
    bool empty() const { return _PathName.empty(); }
    void get_directory_list(std::vector<std::string>& vec_directory);

    bool file_or_directory_exists() const;
    bool is_directory() const;
    bool is_root_directory() const;
    bool is_absolute_path() const;
    filepath remove_trailing_path_separator() const;
    filepath remove_directory_name() const;
    filepath remove_filename() const;
    filepath remove_etension(const char* extension) const;
    static bool remove_directory_or_file(const filepath& path);
    bool create_directories_recursively() const;
    bool create_folder() const;
    bool directory_exists() const;

    static filepath get_current_dir();

    static filepath make_file_name(const filepath& directory,
                                   const filepath& base_name,
                                   int32_t number,
                                   const char* extension);

    static filepath concat_paths(const filepath& directory,
                                 const filepath& relative_path);

    static filepath generate_unique_file_name(const filepath& directory,
                                              const filepath& base_name,
                                              const char* extension);

    static bool create_file(const filepath& path, const std::string& file_name, const std::string& content, int32_t mode = std::fstream::trunc);
    static bool read_file(const filepath& path, const std::string& file_name, std::string& content, ProcessFuncCB func = nullptr);
    static void get_file_list(const filepath& path, std::vector<std::string>& file_list, const std::string& extension);

private:
    void normalize();
    const char* find_last_path_separator() const;

private:
    std::string _PathName;
};
